package concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * TODO 简单说明
 *
 * @author yangyang
 * @date 2017/7/5 15:02
 * @email kekecany@163.com
 */
class Car {

    private volatile boolean waxOn;

    synchronized void waxed() {
        waxOn = true;
        notifyAll();
    }

    synchronized void buffed() {
        waxOn = false;
        notifyAll();
    }

    synchronized void waitingForWaxing() throws InterruptedException {
        while (!waxOn) {
            wait();
        }
    }

    synchronized void waitingForBuffing() throws InterruptedException {
        while (waxOn) {
            wait();
        }
    }
}

class WaxOn implements Runnable {

    private Car car;

    WaxOn(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                car.waitingForBuffing();
                System.out.println("wax on!");
                TimeUnit.MILLISECONDS.sleep(200);
                car.waxed();
            }
        } catch (InterruptedException e) {
            System.out.println("exiting wax on via interruption");
        }
        System.out.println("ending wax on task");
    }
}

class WaxOff implements Runnable {

    private Car car;

    WaxOff(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                car.waitingForWaxing();
                System.out.println("wax off!");
                TimeUnit.MILLISECONDS.sleep(200);
                car.buffed();
            }
        } catch (InterruptedException e) {
            System.out.println("exiting wax off via interruption");
        }
        System.out.println("ending wax off task");
    }
}


public class WaxOMatic {

    public static void main(String[] args) throws InterruptedException {
        Car car = new Car();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new WaxOff(car));
        executorService.execute(new WaxOn(car));
        TimeUnit.SECONDS.sleep(5);
        executorService.shutdownNow();
    }


}
